home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / gas_251.zip / bin_251 / binutils / nm.c < prev    next >
C/C++ Source or Header  |  1994-09-14  |  27KB  |  1,127 lines

  1. /* nm.c -- Describe symbol table of a rel file.
  2.    Copyright 1991, 92, 93, 94 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GNU Binutils.
  5.  
  6.    This program is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2 of the License, or
  9.    (at your option) any later version.
  10.  
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "bfd.h"
  21. #include "sysdep.h"
  22. #include "bucomm.h"
  23. #include "getopt.h"
  24. #include "aout/stab_gnu.h"
  25. #include "aout/ranlib.h"
  26. #include "demangle.h"
  27. #include "libiberty.h"
  28.  
  29. static boolean
  30. display_file PARAMS ((char *filename));
  31.  
  32. static void
  33. display_rel_file PARAMS ((bfd * file, bfd * archive));
  34.  
  35. static unsigned int
  36. filter_symbols PARAMS ((bfd * file, asymbol ** syms, unsigned long symcount));
  37.  
  38. static unsigned int
  39. sort_symbols_by_size PARAMS ((bfd *, asymbol **, unsigned long));
  40.  
  41. static void
  42. print_symbols PARAMS ((bfd * file, asymbol ** syms, unsigned long symcount,
  43.                bfd * archive));
  44.  
  45. static void
  46. print_symdef_entry PARAMS ((bfd * abfd));
  47.  
  48. /* The sorting functions.  */
  49.  
  50. static int
  51. numeric_forward PARAMS ((const PTR, const PTR));
  52.  
  53. static int
  54. numeric_reverse PARAMS ((const PTR, const PTR));
  55.  
  56. static int
  57. non_numeric_forward PARAMS ((const PTR, const PTR));
  58.  
  59. static int
  60. non_numeric_reverse PARAMS ((const PTR, const PTR));
  61.  
  62. static int
  63. size_forward PARAMS ((const PTR, const PTR));
  64.  
  65. /* The output formatting functions.  */
  66.  
  67. static void
  68. print_object_filename_bsd PARAMS ((char *filename));
  69.  
  70. static void
  71. print_object_filename_sysv PARAMS ((char *filename));
  72.  
  73. static void
  74. print_object_filename_posix PARAMS ((char *filename));
  75.  
  76.  
  77. static void
  78. print_archive_filename_bsd PARAMS ((char *filename));
  79.  
  80. static void
  81. print_archive_filename_sysv PARAMS ((char *filename));
  82.  
  83. static void
  84. print_archive_filename_posix PARAMS ((char *filename));
  85.  
  86.  
  87. static void
  88. print_archive_member_bsd PARAMS ((char *archive, CONST char *filename));
  89.  
  90. static void
  91. print_archive_member_sysv PARAMS ((char *archive, CONST char *filename));
  92.  
  93. static void
  94. print_archive_member_posix PARAMS ((char *archive, CONST char *filename));
  95.  
  96.  
  97. static void
  98. print_symbol_filename_bsd PARAMS ((bfd * archive_bfd, bfd * abfd));
  99.  
  100. static void
  101. print_symbol_filename_sysv PARAMS ((bfd * archive_bfd, bfd * abfd));
  102.  
  103. static void
  104. print_symbol_filename_posix PARAMS ((bfd * archive_bfd, bfd * abfd));
  105.  
  106.  
  107. static void
  108. print_symbol_info_bsd PARAMS ((symbol_info * info, bfd * abfd));
  109.  
  110. static void
  111. print_symbol_info_sysv PARAMS ((symbol_info * info, bfd * abfd));
  112.  
  113. static void
  114. print_symbol_info_posix PARAMS ((symbol_info * info, bfd * abfd));
  115.  
  116.  
  117. /* Support for different output formats.  */
  118. struct output_fns
  119.   {
  120.     /* Print the name of an object file given on the command line.  */
  121.     void (*print_object_filename) PARAMS ((char *filename));
  122.  
  123.     /* Print the name of an archive file given on the command line.  */
  124.     void (*print_archive_filename) PARAMS ((char *filename));
  125.  
  126.     /* Print the name of an archive member file.  */
  127.     void (*print_archive_member) PARAMS ((char *archive, CONST char *filename));
  128.  
  129.     /* Print the name of the file (and archive, if there is one)
  130.        containing a symbol.  */
  131.     void (*print_symbol_filename) PARAMS ((bfd * archive_bfd, bfd * abfd));
  132.  
  133.     /* Print a line of information about a symbol.  */
  134.     void (*print_symbol_info) PARAMS ((symbol_info * info, bfd * abfd));
  135.   };
  136. static struct output_fns formats[] =
  137. {
  138.   {print_object_filename_bsd,
  139.    print_archive_filename_bsd,
  140.    print_archive_member_bsd,
  141.    print_symbol_filename_bsd,
  142.    print_symbol_info_bsd},
  143.   {print_object_filename_sysv,
  144.    print_archive_filename_sysv,
  145.    print_archive_member_sysv,
  146.    print_symbol_filename_sysv,
  147.    print_symbol_info_sysv},
  148.   {print_object_filename_posix,
  149.    print_archive_filename_posix,
  150.    print_archive_member_posix,
  151.    print_symbol_filename_posix,
  152.    print_symbol_info_posix}
  153. };
  154.  
  155. /* Indices in `formats'.  */
  156. #define FORMAT_BSD 0
  157. #define FORMAT_SYSV 1
  158. #define FORMAT_POSIX 2
  159. #define FORMAT_DEFAULT FORMAT_BSD
  160.  
  161. /* The output format to use.  */
  162. static struct output_fns *format = &formats[FORMAT_DEFAULT];
  163.  
  164.  
  165. /* Command options.  */
  166.  
  167. static int do_demangle = 0;    /* Pretty print C++ symbol names.  */
  168. static int external_only = 0;    /* print external symbols only */
  169. static int no_sort = 0;        /* don't sort; print syms in order found */
  170. static int print_debug_syms = 0;    /* print debugger-only symbols too */
  171. static int print_armap = 0;    /* describe __.SYMDEF data in archive files.  */
  172. static int reverse_sort = 0;    /* sort in downward(alpha or numeric) order */
  173. static int sort_numerically = 0;    /* sort in numeric rather than alpha order */
  174. static int sort_by_size = 0;    /* sort by size of symbol */
  175. static int undefined_only = 0;    /* print undefined symbols only */
  176. static int dynamic = 0;        /* print dynamic symbols.  */
  177. static int show_version = 0;    /* show the version number */
  178.  
  179. /* When to print the names of files.  Not mutually exclusive in SYSV format.  */
  180. static int filename_per_file = 0;    /* Once per file, on its own line.  */
  181. static int filename_per_symbol = 0;    /* Once per symbol, at start of line.  */
  182.  
  183. /* Print formats for printing a symbol value.  */
  184. #ifdef    BFD_HOST_64_BIT
  185. static char value_format[] = "%08x%08x";
  186. #else
  187. static char value_format[] = "%08lx";
  188. #endif
  189. /* Print formats for printing stab info.  */
  190. static char other_format[] = "%02x";
  191. static char desc_format[] = "%04x";
  192.  
  193. /* IMPORT */
  194. extern char *program_name;
  195. extern char *program_version;
  196. extern char *target;
  197. extern int print_version;
  198.  
  199. static struct option long_options[] =
  200. {
  201.   {"debug-syms", no_argument, &print_debug_syms, 1},
  202.   {"demangle", no_argument, &do_demangle, 1},
  203.   {"dynamic", no_argument, &dynamic, 1},
  204.   {"extern-only", no_argument, &external_only, 1},
  205.   {"format", required_argument, 0, 'f'},
  206.   {"help", no_argument, 0, 'h'},
  207.   {"no-cplus", no_argument, &do_demangle, 0},  /* Linux compatibility.  */
  208.   {"no-demangle", no_argument, &do_demangle, 0},
  209.   {"no-sort", no_argument, &no_sort, 1},
  210.   {"numeric-sort", no_argument, &sort_numerically, 1},
  211.   {"portability", no_argument, 0, 'P'},
  212.   {"print-armap", no_argument, &print_armap, 1},
  213.   {"print-file-name", no_argument, 0, 'o'},
  214.   {"radix", required_argument, 0, 't'},
  215.   {"reverse-sort", no_argument, &reverse_sort, 1},
  216.   {"size-sort", no_argument, &sort_by_size, 1},
  217.   {"target", required_argument, 0, 200},
  218.   {"undefined-only", no_argument, &undefined_only, 1},
  219.   {"version", no_argument, &show_version, 1},
  220.   {0, no_argument, 0, 0}
  221. };
  222.  
  223. /* Some error-reporting functions */
  224.  
  225. void
  226. usage (stream, status)
  227.      FILE *stream;
  228.      int status;
  229. {
  230.   fprintf (stream, "\
  231. Usage: %s [-aABCDgnopPrsuvV] [-t radix] [--radix=radix] [--target=bfdname]\n\
  232.        [--debug-syms] [--extern-only] [--print-armap] [--print-file-name]\n\
  233.        [--numeric-sort] [--no-sort] [--reverse-sort] [--size-sort]\n\
  234.        [--undefined-only] [--portability] [-f {bsd,sysv,posix}]\n\
  235.        [--format={bsd,sysv,posix}] [--demangle] [--no-demangle] [--dynamic]\n\
  236.        [--version] [--help]\n\
  237.        [file...]\n",
  238.        program_name);
  239.   exit (status);
  240. }
  241.  
  242. /* Set the radix for the symbol value and size according to RADIX.  */
  243.  
  244. void
  245. set_print_radix (radix)
  246.      char *radix;
  247. {
  248.   switch (*radix)
  249.     {
  250.     case 'd':
  251.     case 'o':
  252.     case 'x':
  253. #ifdef    BFD_HOST_64_BIT
  254.       value_format[3] = value_format[7] = *radix;
  255. #else
  256.       value_format[4] = *radix;
  257. #endif
  258.       other_format[3] = desc_format[3] = *radix;
  259.       break;
  260.     default:
  261.       fprintf (stderr, "%s: %s: invalid radix\n", program_name, radix);
  262.       exit (1);
  263.     }
  264. }
  265.  
  266. void
  267. set_output_format (f)
  268.      char *f;
  269. {
  270.   int i;
  271.  
  272.   switch (*f)
  273.     {
  274.     case 'b':
  275.     case 'B':
  276.       i = FORMAT_BSD;
  277.       break;
  278.     case 'p':
  279.     case 'P':
  280.       i = FORMAT_POSIX;
  281.       break;
  282.     case 's':
  283.     case 'S':
  284.       i = FORMAT_SYSV;
  285.       break;
  286.     default:
  287.       fprintf (stderr, "%s: %s: invalid output format\n", program_name, f);
  288.       exit (1);
  289.     }
  290.   format = &formats[i];
  291. }
  292.  
  293. int
  294. main (argc, argv)
  295.      int argc;
  296.      char **argv;
  297. {
  298.   int c;
  299.   int retval;
  300.  
  301.   program_name = *argv;
  302.   xmalloc_set_program_name (program_name);
  303.  
  304.   bfd_init ();
  305.  
  306.   while ((c = getopt_long (argc, argv, "aABCDf:gnopPrst:uvV", long_options, (int *) 0)) != EOF)
  307.     {
  308.       switch (c)
  309.     {
  310.     case 'a':
  311.       print_debug_syms = 1;
  312.       break;
  313.     case 'A':
  314.     case 'o':
  315.       filename_per_symbol = 1;
  316.       break;
  317.     case 'B':        /* For MIPS compatibility.  */
  318.       set_output_format ("bsd");
  319.       break;
  320.     case 'C':
  321.       do_demangle = 1;
  322.       break;
  323.     case 'D':
  324.       dynamic = 1;
  325.       break;
  326.     case 'f':
  327.       set_output_format (optarg);
  328.       break;
  329.     case 'g':
  330.       external_only = 1;
  331.       break;
  332.     case 'h':
  333.       usage (stdout, 0);
  334.     case 'n':
  335.     case 'v':
  336.       sort_numerically = 1;
  337.       break;
  338.     case 'p':
  339.       no_sort = 1;
  340.       break;
  341.     case 'P':
  342.       set_output_format ("posix");
  343.       break;
  344.     case 'r':
  345.       reverse_sort = 1;
  346.       break;
  347.     case 's':
  348.       print_armap = 1;
  349.       break;
  350.     case 't':
  351.       set_print_radix (optarg);
  352.       break;
  353.     case 'u':
  354.       undefined_only = 1;
  355.       break;
  356.     case 'V':
  357.       show_version = 1;
  358.       break;
  359.  
  360.     case 200:        /* --target */
  361.       target = optarg;
  362.       break;
  363.  
  364.     case 0:        /* A long option that just sets a flag.  */
  365.       break;
  366.  
  367.     default:
  368.       usage (stderr, 1);
  369.     }
  370.     }
  371.  
  372.   if (show_version)
  373.     {
  374.       printf ("GNU %s version %s\n", program_name, program_version);
  375.       exit (0);
  376.     }
  377.  
  378.   /* OK, all options now parsed.  If no filename specified, do a.out.  */
  379.   if (optind == argc)
  380.     return !display_file ("a.out");
  381.  
  382.   retval = 0;
  383.  
  384.   if (argc - optind > 1)
  385.     filename_per_file = 1;
  386.  
  387.   /* We were given several filenames to do.  */
  388.   while (optind < argc)
  389.     {
  390.       if (!display_file (argv[optind++]))
  391.     retval++;
  392.     }
  393.  
  394.   exit (retval);
  395.   return retval;
  396. }
  397.  
  398. static void
  399. display_archive (file)
  400.      bfd *file;
  401. {
  402.   bfd *arfile = NULL;
  403.   bfd *last_arfile = NULL;
  404.   char **matching;
  405.  
  406.   (*format->print_archive_filename) (bfd_get_filename (file));
  407.  
  408.   if (print_armap)
  409.     print_symdef_entry (file);
  410.  
  411.   for (;;)
  412.     {
  413.       arfile = bfd_openr_next_archived_file (file, arfile);
  414.  
  415.       if (arfile == NULL)
  416.     {
  417.       if (bfd_get_error () != bfd_error_no_more_archived_files)
  418.         bfd_fatal (bfd_get_filename (file));
  419.       break;
  420.     }
  421.  
  422.       if (bfd_check_format_matches (arfile, bfd_object, &matching))
  423.     {
  424.       (*format->print_archive_member) (bfd_get_filename (file),
  425.                        bfd_get_filename (arfile));
  426.       display_rel_file (arfile, file);
  427.     }
  428.       else
  429.     {
  430.       bfd_nonfatal (bfd_get_filename (arfile));
  431.       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
  432.         {
  433.           list_matching_formats (matching);
  434.           free (matching);
  435.         }
  436.     }
  437.  
  438.       if (last_arfile != NULL)
  439.     bfd_close (last_arfile);
  440.       last_arfile = arfile;
  441.     }
  442.  
  443.   if (last_arfile != NULL)
  444.     bfd_close (last_arfile);
  445. }
  446.  
  447. static boolean
  448. display_file (filename)
  449.      char *filename;
  450. {
  451.   boolean retval = true;
  452.   bfd *file;
  453.   char **matching;
  454.  
  455.   file = bfd_openr (filename, target);
  456.   if (file == NULL)
  457.     {
  458.       bfd_nonfatal (filename);
  459.       return false;
  460.     }
  461.  
  462.   if (bfd_check_format (file, bfd_archive))
  463.     {
  464.       display_archive (file);
  465.     }
  466.   else if (bfd_check_format_matches (file, bfd_object, &matching))
  467.     {
  468.       (*format->print_object_filename) (filename);
  469.       display_rel_file (file, NULL);
  470.     }
  471.   else
  472.     {
  473.       bfd_nonfatal (filename);
  474.       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
  475.     {
  476.       list_matching_formats (matching);
  477.       free (matching);
  478.     }
  479.       retval = false;
  480.     }
  481.  
  482.   if (bfd_close (file) == false)
  483.     bfd_fatal (filename);
  484.  
  485.   return retval;
  486. }
  487.  
  488. /* Symbol-sorting predicates */
  489. #define valueof(x) ((x)->section->vma + (x)->value)
  490.  
  491. /* Numeric sorts.  Undefined symbols are always considered "less than"
  492.    defined symbols with zero values.  Common symbols are not treated
  493.    specially -- i.e., their sizes are used as their "values".  */
  494. static int
  495. numeric_forward (P_x, P_y)
  496.      const PTR P_x;
  497.      const PTR P_y;
  498. {
  499.   asymbol *x = *(asymbol **) P_x;
  500.   asymbol *y = *(asymbol **) P_y;
  501.   asection *xs = bfd_get_section (x);
  502.   asection *ys = bfd_get_section (y);
  503.   if (bfd_is_und_section (xs))
  504.     {
  505.       if (bfd_is_und_section (ys))
  506.     goto equal;
  507.       return -1;
  508.     }
  509.   else if (bfd_is_und_section (ys))
  510.     return 1;
  511.   /* Don't just return the difference -- in cross configurations,
  512.      after truncation to `int' it might not have the sign we want.  */
  513.   if (valueof (x) != valueof (y))
  514.     return valueof (x) < valueof (y) ? -1 : 1;
  515.  equal:
  516.   return non_numeric_forward (P_x, P_y);
  517. }
  518.  
  519. static int
  520. numeric_reverse (x, y)
  521.      const PTR x;
  522.      const PTR y;
  523. {
  524.   return -numeric_forward (x, y);
  525. }
  526.  
  527. static int
  528. non_numeric_forward (x, y)
  529.      const PTR x;
  530.      const PTR y;
  531. {
  532.   CONST char *xn = (*(asymbol **) x)->name;
  533.   CONST char *yn = (*(asymbol **) y)->name;
  534.  
  535.   return ((xn == NULL) ? ((yn == NULL) ? 0 : -1) :
  536.       ((yn == NULL) ? 1 : strcmp (xn, yn)));
  537. }
  538.  
  539. static int
  540. non_numeric_reverse (x, y)
  541.      const PTR x;
  542.      const PTR y;
  543. {
  544.   return -non_numeric_forward (x, y);
  545. }
  546.  
  547. static int (*(sorters[2][2])) PARAMS ((const PTR, const PTR)) =
  548. {
  549.   { non_numeric_forward, non_numeric_reverse },
  550.   { numeric_forward, numeric_reverse }
  551. };
  552.  
  553. /* This sort routine is used by sort_symbols_by_size.  It is similar
  554.    to numeric_forward, but when symbols have the same value it sorts
  555.    by section VMA.  This simplifies the sort_symbols_by_size code
  556.    which handles symbols at the end of sections.  Also, this routine
  557.    tries to sort file names before other symbols with the same value.
  558.    That will make the file name have a zero size, which will make
  559.    sort_symbols_by_size choose the non file name symbol, leading to
  560.    more meaningful output.  For similar reasons, this code sorts
  561.    gnu_compiled_* and gcc2_compiled before other symbols with the same
  562.    value.  */
  563.  
  564. static int
  565. size_forward (P_x, P_y)
  566.      const PTR P_x;
  567.      const PTR P_y;
  568. {
  569.   asymbol *x = *(asymbol **) P_x;
  570.   asymbol *y = *(asymbol **) P_y;
  571.   asection *xs = bfd_get_section (x);
  572.   asection *ys = bfd_get_section (y);
  573.   const char *xn;
  574.   const char *yn;
  575.   size_t xnl;
  576.   size_t ynl;
  577.   int xf;
  578.   int yf;
  579.  
  580.   if (bfd_is_und_section (xs))
  581.     abort ();
  582.   if (bfd_is_und_section (ys))
  583.     abort ();
  584.  
  585.   if (valueof (x) != valueof (y))
  586.     return valueof (x) < valueof (y) ? -1 : 1;
  587.  
  588.   if (xs->vma != ys->vma)
  589.     return xs->vma < ys->vma ? -1 : 1;
  590.  
  591.   xn = bfd_asymbol_name (x);
  592.   yn = bfd_asymbol_name (y);
  593.   xnl = strlen (xn);
  594.   ynl = strlen (yn);
  595.  
  596.   /* The symbols gnu_compiled and gcc2_compiled convey even less
  597.      information than the file name, so sort them out first.  */
  598.  
  599.   xf = (strstr (xn, "gnu_compiled") != NULL
  600.     || strstr (xn, "gcc2_compiled") != NULL);
  601.   yf = (strstr (xn, "gnu_compiled") != NULL
  602.     || strstr (xn, "gcc2_compiled") != NULL);
  603.  
  604.   if (xf && ! yf)
  605.     return -1;
  606.   if (! xf && yf)
  607.     return 1;
  608.  
  609.   /* We use a heuristic for the file name.  It may not work on non
  610.      Unix systems, but it doesn't really matter; the only difference
  611.      is precisely which symbol names get printed.  */
  612.  
  613. #define file_symbol(s, sn, snl)            \
  614.   ((s->flags & BSF_FILE) != 0            \
  615.    || (sn[snl - 2] == '.'            \
  616.        && (sn[snl - 1] == 'o'            \
  617.        || sn[snl - 1] == 'a')))
  618.  
  619.   xf = file_symbol (x, xn, xnl);
  620.   yf = file_symbol (y, yn, ynl);
  621.  
  622.   if (xf && ! yf)
  623.     return -1;
  624.   if (! xf && yf)
  625.     return 1;
  626.  
  627.   return non_numeric_forward (P_x, P_y);
  628. }
  629.  
  630. /* Sort the symbols by size.  We guess the size by assuming that the
  631.    difference between the address of a symbol and the address of the
  632.    next higher symbol is the size.  FIXME: ELF actually stores a size
  633.    with each symbol.  We should use it.  */
  634.  
  635. static unsigned int
  636. sort_symbols_by_size (abfd, syms, symcount)
  637.      bfd *abfd;
  638.      asymbol **syms;
  639.      unsigned long symcount;
  640. {
  641.   asymbol **from, **to;
  642.   unsigned int src_count;
  643.   unsigned int dst_count = 0;
  644.   asymbol *sym;
  645.   asection *sec;
  646.  
  647.   qsort ((PTR) syms, symcount, sizeof (asymbol *), size_forward);
  648.  
  649.   /* Note that filter_symbols has already removed all absolute and
  650.      undefined symbols.  Here we remove all symbols whose size winds
  651.      up as zero.  */
  652.  
  653.   for (from = to = syms, src_count = 0; src_count < symcount; src_count++)
  654.     {
  655.       bfd_vma size;
  656.  
  657.       sym = from[src_count];
  658.       sec = bfd_get_section (sym);
  659.  
  660.       if (bfd_is_com_section (sec))
  661.     size = sym->value;
  662.       else
  663.     {
  664.       if (src_count + 1 < symcount
  665.           && sec == bfd_get_section (from[src_count + 1]))
  666.         size = valueof (from[src_count + 1]) - valueof (sym);
  667.       else
  668.         size = (bfd_get_section_vma (abfd, sec)
  669.             + bfd_section_size (abfd, sec)
  670.             - valueof (sym));
  671.     }
  672.  
  673.       if (size != 0)
  674.     {
  675.       /* We adjust the value of the symbol so that when it is
  676.              printed out, it will actually be the size.  */
  677.       sym->value = size - bfd_get_section_vma (abfd, sec);
  678.  
  679.       to[dst_count++] = sym;
  680.     }
  681.     }
  682.  
  683.   /* We must now sort again by size.  */
  684.   qsort ((PTR) syms, dst_count, sizeof (asymbol *), sorters[1][reverse_sort]);
  685.  
  686.   return dst_count;
  687. }
  688.  
  689. /* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD.  */
  690.  
  691. static void
  692. display_rel_file (abfd, archive_bfd)
  693.      bfd *abfd;
  694.      bfd *archive_bfd;
  695. {
  696.   long storage;
  697.   asymbol **syms;
  698.   long symcount = 0;
  699.  
  700.   if (dynamic)
  701.     {
  702.       if (!(bfd_get_file_flags (abfd) & DYNAMIC))
  703.     {
  704.       printf ("\"%s\" is not a dynamic object.\n",
  705.           bfd_get_filename (abfd));
  706.       return;
  707.     }
  708.     }
  709.   else
  710.     {
  711.       if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
  712.     {
  713.       printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
  714.       return;
  715.     }
  716.     }
  717.  
  718.   if (dynamic)
  719.     storage = bfd_get_dynamic_symtab_upper_bound (abfd);
  720.   else
  721.     storage = bfd_get_symtab_upper_bound (abfd);
  722.   if (storage < 0)
  723.     bfd_fatal (bfd_get_filename (abfd));
  724.   if (storage == 0)
  725.     {
  726.     nosymz:
  727.       if (dynamic)
  728.     fprintf (stderr, "%s: no symbols\n", bfd_get_filename (abfd));
  729.       else
  730.     fprintf (stderr, "%s: Symflags set but there are none?\n",
  731.          bfd_get_filename (abfd));
  732.       return;
  733.     }
  734.  
  735.   syms = (asymbol **) xmalloc (storage);
  736.  
  737.   if (dynamic)
  738.     symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
  739.   else
  740.     symcount = bfd_canonicalize_symtab (abfd, syms);
  741.   if (symcount < 0)
  742.     bfd_fatal (bfd_get_filename (abfd));
  743.   if (symcount == 0)
  744.     {
  745.       free (syms);
  746.       goto nosymz;
  747.     }
  748.  
  749.   /* Discard the symbols we don't want to print.
  750.      It's OK to do this in place; we'll free the storage anyway
  751.      (after printing).  */
  752.  
  753.   symcount = filter_symbols (abfd, syms, symcount);
  754.  
  755.   if (!no_sort)
  756.     {
  757.       if (! sort_by_size)
  758.     qsort ((char *) syms, symcount, sizeof (asymbol *),
  759.            sorters[sort_numerically][reverse_sort]);
  760.       else
  761.     symcount = sort_symbols_by_size (abfd, syms, symcount);
  762.     }
  763.  
  764.   print_symbols (abfd, syms, symcount, archive_bfd);
  765.   free (syms);
  766. }
  767.  
  768. /* Choose which symbol entries to print;
  769.    compact them downward to get rid of the rest.
  770.    Return the number of symbols to be printed.  */
  771.  
  772. static unsigned int
  773. filter_symbols (abfd, syms, symcount)
  774.      bfd *abfd;            /* Unused.  */
  775.      asymbol **syms;
  776.      unsigned long symcount;
  777. {
  778.   asymbol **from, **to;
  779.   unsigned int src_count;
  780.   unsigned int dst_count = 0;
  781.   asymbol *sym;
  782.  
  783.   for (from = to = syms, src_count = 0; src_count < symcount; src_count++)
  784.     {
  785.       int keep = 0;
  786.       flagword flags = (from[src_count])->flags;
  787.  
  788.       sym = from[src_count];
  789.       if (undefined_only)
  790.     keep = bfd_is_und_section (sym->section);
  791.       else if (external_only)
  792.     keep = ((flags & BSF_GLOBAL)
  793.         || bfd_is_und_section (sym->section)
  794.         || bfd_is_com_section (sym->section));
  795.       else
  796.     keep = 1;
  797.  
  798.       if (!print_debug_syms && ((flags & BSF_DEBUGGING) != 0))
  799.     keep = 0;
  800.  
  801.       if (sort_by_size
  802.       && (bfd_is_abs_section (sym->section)
  803.           || bfd_is_und_section (sym->section)))
  804.     keep = 0;
  805.  
  806.       if (keep)
  807.     to[dst_count++] = from[src_count];
  808.     }
  809.  
  810.   return dst_count;
  811. }
  812.  
  813. /* Print symbol name NAME, read from ABFD, with printf format FORMAT,
  814.    demangling it if requested.  */
  815.  
  816. static void
  817. print_symname (format, name, abfd)
  818.      char *format, *name;
  819.      bfd *abfd;
  820. {
  821.   if (do_demangle)
  822.     {
  823.       char *res;
  824.  
  825.       /* In this mode, give a user-level view of the symbol name
  826.      even if it's not mangled; strip off any leading
  827.      underscore.  */
  828.       if (bfd_get_symbol_leading_char (abfd) == name[0])
  829.     name++;
  830.  
  831.       res = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
  832.       if (res)
  833.     {
  834.       printf (format, res);
  835.       free (res);
  836.       return;
  837.     }
  838.     }
  839.  
  840.   printf (format, name);
  841. }
  842.  
  843. /* If ARCHIVE_BFD is non-NULL, it is the archive containing ABFD.  */
  844.  
  845. static void
  846. print_symbols (abfd, syms, symcount, archive_bfd)
  847.      bfd *abfd;
  848.      asymbol **syms;
  849.      unsigned long symcount;
  850.      bfd *archive_bfd;
  851. {
  852.   asymbol **sym = syms, **end = syms + symcount;
  853.   symbol_info syminfo;
  854.  
  855.   for (; sym < end; ++sym)
  856.     {
  857.       (*format->print_symbol_filename) (archive_bfd, abfd);
  858.  
  859.       if (undefined_only)
  860.     {
  861.       if (bfd_is_und_section ((*sym)->section))
  862.         {
  863.           print_symname ("%s\n", (*sym)->name, abfd);
  864.         }
  865.     }
  866.       else
  867.     {
  868.       asymbol *p = *sym;
  869.       if (p)
  870.         {
  871.           bfd_get_symbol_info (abfd, p, &syminfo);
  872.           (*format->print_symbol_info) (&syminfo, abfd);
  873.           putchar ('\n');
  874.         }
  875.     }
  876.     }
  877. }
  878.  
  879. /* The following 3 groups of functions are called unconditionally,
  880.    once at the start of processing each file of the appropriate type.
  881.    They should check `filename_per_file' and `filename_per_symbol',
  882.    as appropriate for their output format, to determine whether to
  883.    print anything.  */
  884.  
  885. /* Print the name of an object file given on the command line.  */
  886.  
  887. static void
  888. print_object_filename_bsd (filename)
  889.      char *filename;
  890. {
  891.   if (filename_per_file && !filename_per_symbol)
  892.     printf ("\n%s:\n", filename);
  893. }
  894.  
  895. static void
  896. print_object_filename_sysv (filename)
  897.      char *filename;
  898. {
  899.   if (undefined_only)
  900.     printf ("\n\nUndefined symbols from %s:\n\n", filename);
  901.   else
  902.     printf ("\n\nSymbols from %s:\n\n", filename);
  903.   printf ("\
  904. Name                  Value   Class        Type         Size   Line  Section\n\n");
  905. }
  906.  
  907. static void
  908. print_object_filename_posix (filename)
  909.      char *filename;
  910. {
  911.   if (filename_per_file && !filename_per_symbol)
  912.     printf ("%s:\n", filename);
  913. }
  914.  
  915. /* Print the name of an archive file given on the command line.  */
  916.  
  917. static void
  918. print_archive_filename_bsd (filename)
  919.      char *filename;
  920. {
  921.   if (filename_per_file)
  922.     printf ("\n%s:\n", filename);
  923. }
  924.  
  925. static void
  926. print_archive_filename_sysv (filename)
  927.      char *filename;
  928. {
  929. }
  930.  
  931. static void
  932. print_archive_filename_posix (filename)
  933.      char *filename;
  934. {
  935. }
  936.  
  937. /* Print the name of an archive member file.  */
  938.  
  939. static void
  940. print_archive_member_bsd (archive, filename)
  941.      char *archive;
  942.      CONST char *filename;
  943. {
  944.   if (!filename_per_symbol)
  945.     printf ("\n%s:\n", filename);
  946. }
  947.  
  948. static void
  949. print_archive_member_sysv (archive, filename)
  950.      char *archive;
  951.      CONST char *filename;
  952. {
  953.   if (undefined_only)
  954.     printf ("\n\nUndefined symbols from %s[%s]:\n\n", archive, filename);
  955.   else
  956.     printf ("\n\nSymbols from %s[%s]:\n\n", archive, filename);
  957.   printf ("\
  958. Name                  Value   Class        Type         Size   Line  Section\n\n");
  959. }
  960.  
  961. static void
  962. print_archive_member_posix (archive, filename)
  963.      char *archive;
  964.      CONST char *filename;
  965. {
  966.   if (!filename_per_symbol)
  967.     printf ("%s[%s]:\n", archive, filename);
  968. }
  969.  
  970. /* Print the name of the file (and archive, if there is one)
  971.    containing a symbol.  */
  972.  
  973. static void
  974. print_symbol_filename_bsd (archive_bfd, abfd)
  975.      bfd *archive_bfd, *abfd;
  976. {
  977.   if (filename_per_symbol)
  978.     {
  979.       if (archive_bfd)
  980.     printf ("%s:", bfd_get_filename (archive_bfd));
  981.       printf ("%s:", bfd_get_filename (abfd));
  982.     }
  983. }
  984.  
  985. static void
  986. print_symbol_filename_sysv (archive_bfd, abfd)
  987.      bfd *archive_bfd, *abfd;
  988. {
  989.   if (filename_per_symbol)
  990.     {
  991.       if (archive_bfd)
  992.     printf ("%s:", bfd_get_filename (archive_bfd));
  993.       printf ("%s:", bfd_get_filename (abfd));
  994.     }
  995. }
  996.  
  997. static void
  998. print_symbol_filename_posix (archive_bfd, abfd)
  999.      bfd *archive_bfd, *abfd;
  1000. {
  1001.   if (filename_per_symbol)
  1002.     {
  1003.       if (archive_bfd)
  1004.     printf ("%s[%s]: ", bfd_get_filename (archive_bfd),
  1005.         bfd_get_filename (abfd));
  1006.       else
  1007.     printf ("%s: ", bfd_get_filename (abfd));
  1008.     }
  1009. }
  1010.  
  1011. /* Print a line of information about a symbol.  */
  1012.  
  1013. static void
  1014. print_symbol_info_bsd (info, abfd)
  1015.      symbol_info *info;
  1016.      bfd *abfd;
  1017. {
  1018.   if (info->type == 'U')
  1019.     {
  1020.       printf ("%*s",
  1021. #ifdef BFD_HOST_64_BIT
  1022.           16,
  1023. #else
  1024.           8,
  1025. #endif
  1026.           "");
  1027.     }
  1028.   else
  1029.     {
  1030. #ifdef BFD_HOST_64_BIT
  1031.       printf (value_format, uint64_typeHIGH (info->value),
  1032.           uint64_typeLOW (info->value));
  1033. #else
  1034.       printf (value_format, info->value);
  1035. #endif
  1036.     }
  1037.   printf (" %c", info->type);
  1038.   if (info->type == '-')
  1039.     {
  1040.       /* A stab.  */
  1041.       printf (" ");
  1042.       printf (other_format, info->stab_other);
  1043.       printf (" ");
  1044.       printf (desc_format, info->stab_desc);
  1045.       printf (" %5s", info->stab_name);
  1046.     }
  1047.   print_symname (" %s", info->name, abfd);
  1048. }
  1049.  
  1050. static void
  1051. print_symbol_info_sysv (info, abfd)
  1052.      symbol_info *info;
  1053.      bfd *abfd;
  1054. {
  1055.   print_symname ("%-20s|", info->name, abfd);    /* Name */
  1056.   if (info->type == 'U')
  1057.     printf ("        ");    /* Value */
  1058.   else
  1059.     {
  1060. #ifdef BFD_HOST_64_BIT
  1061.       printf (value_format, uint64_typeHIGH (info->value),
  1062.           uint64_typeLOW (info->value));
  1063. #else
  1064.       printf (value_format, info->value);
  1065. #endif
  1066.     }
  1067.   printf ("|   %c  |", info->type);    /* Class */
  1068.   if (info->type == '-')
  1069.     {
  1070.       /* A stab.  */
  1071.       printf ("%18s|  ", info->stab_name);    /* (C) Type */
  1072.       printf (desc_format, info->stab_desc);    /* Size */
  1073.       printf ("|     |");    /* Line, Section */
  1074.     }
  1075.   else
  1076.     printf ("                  |      |     |");    /* Type, Size, Line, Section */
  1077. }
  1078.  
  1079. static void
  1080. print_symbol_info_posix (info, abfd)
  1081.      symbol_info *info;
  1082.      bfd *abfd;
  1083. {
  1084.   print_symname ("%s ", info->name, abfd);
  1085.   printf ("%c ", info->type);
  1086.   if (info->type == 'U')
  1087.     printf ("        ");
  1088.   else
  1089.     {
  1090. #ifdef BFD_HOST_64_BIT
  1091.       printf (value_format, uint64_typeHIGH (info->value),
  1092.           uint64_typeLOW (info->value));
  1093. #else
  1094.       printf (value_format, info->value);
  1095. #endif
  1096.     }
  1097.   /* POSIX.2 wants the symbol size printed here, when applicable;
  1098.      BFD currently doesn't provide it, so we take the easy way out by
  1099.      considering it to never be applicable.  */
  1100. }
  1101.  
  1102. static void
  1103. print_symdef_entry (abfd)
  1104.      bfd *abfd;
  1105. {
  1106.   symindex idx = BFD_NO_MORE_SYMBOLS;
  1107.   carsym *thesym;
  1108.   boolean everprinted = false;
  1109.  
  1110.   for (idx = bfd_get_next_mapent (abfd, idx, &thesym);
  1111.        idx != BFD_NO_MORE_SYMBOLS;
  1112.        idx = bfd_get_next_mapent (abfd, idx, &thesym))
  1113.     {
  1114.       bfd *elt;
  1115.       if (!everprinted)
  1116.     {
  1117.       printf ("\nArchive index:\n");
  1118.       everprinted = true;
  1119.     }
  1120.       elt = bfd_get_elt_at_index (abfd, idx);
  1121.       if (thesym->name != (char *) NULL)
  1122.     {
  1123.       printf ("%s in %s\n", thesym->name, bfd_get_filename (elt));
  1124.     }
  1125.     }
  1126. }
  1127.